#include "stdio.h"
#include "EmAES.h"
#include "stdlib.h"
#include "stdint.h"

void printusage(void)
{
    printf("Usage:\r\n");
    printf("        aes encry/decry[128/192/256] infile outfile [keyfile]\r\n");
    printf("        aes encry infile outfile :use AES128 and default key\r\n");
    printf("        aes encry256 infile outfile keyfile :use AES256 and user key\r\n\r\n");
}

int main(int argc,char *argv[])
{
    uint16_t keybits = 128;
    unsigned char chainCipherBlock[16] = {	0xf0,0x4E,0x42,0x19, 
                                            0x40,0x4B,0x89,0x47, 
                                            0x4f,0x09,0x4a,0xeb, 
                                            0x02,0x4A,0x4e,0x75,
                                        };
    if(argc == 1)
    {
        printusage();
        return 0;
    }
    if(strstr(argv[1],"encry"))
    {
        keybits = atoi(strstr(argv[1],"encry") + 5);    
    }
    else if(strstr(argv[1],"decry"))
    {
        keybits = atoi(strstr(argv[1],"decry") + 5);    
    }
    keybits = (keybits ? keybits : 128);
    printf("AES%3d \r\n",keybits);
    
    if(argc < 4)
    {
        unsigned char dat[32] = {	0x40,0x27,0x22,0x43,
                                    0x29,0x28,0x24,0x21,
                                    0x08,0x9f,0x2a,0x2b,
                                    0x2c,0x2d,0x2e,0x2f,
                                    0x05,0x7e,0xdd,0xcc,
                                    0x34,0xaa,0x99,0x88,
                                    0x44,0x66,0x55,0x44,
                                    0x55,0x22,0x11,0x00,
                                };

        unsigned int i = 0x11223344;
        unsigned char *j = 0;

        printusage();

        j = (unsigned char *)(&i);
        
        printf("存储模式：");
        printf("0x11223344 -> 0:0x%02X 1:0x%02X 2:0x%02X 3:0x%02X \r\n",j[0],j[1],j[2],j[3]);//	0X44 0X33 0X22 0X11 小端存储 

        printf("原始数据：");
        for(i = 0; i < 32; i++)
        {
            printf("%02X ",dat[i]);
            if(i == 15)
                printf("\b, ");
        }
        printf("\r\n");

        printf("秘　　钥：");
        for(i = 0; i < 16; i++)
        {
            printf("%02X ",chainCipherBlock[i]);
        }
        printf("\r\n");


        //加密
        aesEncInit(keybits);
        aesEncrypt(dat, chainCipherBlock);
        aesEncrypt(dat+16, chainCipherBlock);
        
        printf("加密数据：");
        for(i = 0; i < 32; i++)
        {
            printf("%02X ",dat[i]);
            if(i == 15)
                printf("\b, ");
        }
        printf("\r\n");

        //解密
        aesDecInit(keybits);
        aesDecrypt(dat, chainCipherBlock);
        aesDecrypt(dat+16, chainCipherBlock);
        
        printf("解密数据：");
        for(i = 0; i < 32; i++)
        {
            printf("%02X ",dat[i]);
            if(i == 15)
                printf("\b, ");
        }
        printf("\r\n");
    }
    else
    {
        FILE *fs = NULL,*fo = NULL,*fd = NULL;
        uint32_t filesize = 0;
        uint8_t data[16] = {0},readcount = 0,i = 0;
        
        if(argc == 5)
        {
            FILE *fk = NULL;
            if((fk = fopen(argv[4],"r")) == NULL) 
            {
                printf("key file open error\r\n");
                return 0;
            }
            for(i = 0;i < 16;i ++)
            {
                readcount = fread(data,1,2,fk); 
                if(readcount != 2)
                {
                   break; 
                }
                chainCipherBlock[i] = strtol(data,NULL,16);
            }
            fclose(fk);
        }
        printf("秘　　钥：");
        for(i = 0; i < 16; i++)
        {
            printf("%02X ",chainCipherBlock[i]);
        }
        printf("\r\n");
        
        if(strstr(argv[1],"encry") != NULL)
        {
            
            if((fs = fopen(argv[2],"r")) == NULL) 
            {
                printf("file open error\r\n");
                return 0;
            }
            if((fo = fopen(argv[3],"w")) == NULL) 
            {
                printf("file open error\r\n");
                return 0;
            }

            fseek(fs,0,SEEK_END);
            filesize = ftell(fs);
            fseek(fs,0,SEEK_SET);

            aesEncInit(keybits);

            printf("加密中...      ");
            while((readcount = fread(data,1,16,fs)))
            {
                if(readcount == 16) 
                {
                    aesEncrypt(data, chainCipherBlock);
                    fwrite(data,1,16,fo);
                }
                else if(readcount < 16)
                {
                   // for(i = readcount;i < 16;i ++) 
                   // {
                   //     data[i] = 0; 
                   // }
                   // aesEncrypt(data, chainCipherBlock);
                    fwrite(data,1,readcount,fo);
                }
                printf("\b\b\b\b%3d%%",(ftell(fs) * 100/filesize));
                fflush(stdout);
            }
            fclose(fs);
            fclose(fo);
            printf("\r\n加密完成");
        }

        if(strstr(argv[1],"decry") != NULL)
        {
            if((fo = fopen(argv[2],"r")) == NULL) 
            {
                printf("file open error\r\n");
                return 0;
            }
            if((fd = fopen(argv[3],"w")) == NULL) 
            {
                printf("file open error\r\n");
                return 0;
            }

            fseek(fo,0,SEEK_END);
            filesize = ftell(fo);
            fseek(fo,0,SEEK_SET);

            aesDecInit(keybits);

            printf("解密中...      ");
            while((readcount = fread(data,1,16,fo)))
            {
                if(readcount == 16) 
                {
                    aesDecrypt(data, chainCipherBlock);
                    fwrite(data,1,16,fd);
                }
                else if(readcount < 16)
                {
                   // for(i = readcount;i < 16;i ++) 
                   // {
                   //     data[i] = 0; 
                   // }
                   // aesDecrypt(data, chainCipherBlock);
                    fwrite(data,1,readcount,fd);
                }
                printf("\b\b\b\b%3d%%",(ftell(fo) * 100/filesize));
                fflush(stdout);
            }
            fclose(fd);
            fclose(fo);
            printf("\r\n解密完成");
        }
    }
    printf("\r\n");

	return 0;
}


